<template>
  <div class="dot-batch-page">
    <div class="content-wrapper">
            <!-- Modern Header Section -->
            <div class="header-section">
              <div class="header-content">
                <h1 class="main-title">DoT 批量验证</h1>
                <p class="subtitle">批量验证递归服务器的 DoT 配置和证书状态</p>
              </div>
              <div class="header-actions">
                <el-tooltip content="了解更多关于DoT验证" placement="top">
                  <el-button type="info" icon="InfoFilled" circle></el-button>
                </el-tooltip>
              </div>
            </div>

            <!-- Upload Section -->
            <div class="upload-container">
              <div class="upload-card" 
                   :class="{ 'is-dragover': isDragover, 'has-file': file }"
                   @dragover.prevent="isDragover = true"
                   @dragleave.prevent="isDragover = false"
                   @drop.prevent="handleFileDrop">
                <div class="upload-area">
                  <el-icon class="upload-icon" :class="{ 'success': file }">
                    <component :is="file ? 'CircleCheckFilled' : 'Upload'" />
                  </el-icon>
                  <h3 class="upload-title">{{ uploadBtnText }}</h3>
                  <p class="upload-hint">
                    {{ file ? '文件已选择，可以开始探测' : '支持拖拽上传或点击选择文件' }}
                  </p>
                  <input 
                    type="file" 
                    @change="handleFileUpload" 
                    accept=".txt"
                    class="file-input" 
                  />
                </div>
                
                <div class="action-panel">
                  <el-button
                    type="primary"
                    size="large"
                    :icon="file ? 'VideoPlay' : 'Upload'"
                    :loading="detectStatus === '正在探测'"
                    :disabled="!file"
                    @click="startDetection"
                    class="action-button primary-action"
                  >
                    {{ detectStatus }}
                  </el-button>

                  <el-button
                    type="success"
                    size="large"
                    icon="Download"
                    :disabled="!results.length"
                    @click="downloadResult"
                    class="action-button"
                  >
                    导出 JSON
                  </el-button>

                  <el-button
                    type="info"
                    size="large"
                    icon="Upload"
                    @click="importResults"
                    class="action-button"
                  >
                    导入结果
                  </el-button>
                </div>
              </div>
            </div>

            <!-- Results Dashboard -->
            <transition name="fade">
              <div v-if="results.length > 0" class="results-dashboard">
                <!-- Statistics Cards -->
                <div class="stats-grid stats-overview">
                  <div class="stat-card primary-card">
                    <div class="stat-icon">
                      <el-icon><Check /></el-icon>
                    </div>
                    <div class="stat-info">
                      <span class="stat-value">{{ stats.dot_supported_count }}</span>
                      <span class="stat-label">支持 DoT 服务</span>
                    </div>
                  </div>

                  <div class="stat-card success-card">
                    <div class="stat-icon">
                      <el-icon><Lock /></el-icon>
                    </div>
                    <div class="stat-info">
                      <span class="stat-value">{{ stats.cert_valid_count }}</span>
                      <span class="stat-label">证书有效</span>
                    </div>
                  </div>

                  <div class="stat-card warning-card">
                    <div class="stat-icon">
                      <el-icon><Warning /></el-icon>
                    </div>
                    <div class="stat-info">
                      <span class="stat-value">{{ stats.cert_expired_count }}</span>
                      <span class="stat-label">证书过期</span>
                    </div>
                  </div>

                  <div class="stat-card info-card">
                    <div class="stat-icon">
                      <el-icon><Key /></el-icon>
                    </div>
                    <div class="stat-info">
                      <span class="stat-value">{{ stats.self_signed_count }}</span>
                      <span class="stat-label">自签名证书</span>
                    </div>
                  </div>
                </div>

                <!-- Results Table Section -->
                <div class="results-section">
                  <div class="section-header">
                    <div class="header-left">
                      <h2 class="section-title">验证结果</h2>
                      <el-tag type="info" effect="plain" class="result-count">
                        {{ results.length }} 条记录
                      </el-tag>
                    </div>
                    <div class="header-right">
                      <el-input
                        v-model="searchQuery"
                        placeholder="搜索IP地址..."
                        prefix-icon="Search"
                        clearable
                        class="search-input"
                      />
                    </div>
                  </div>

                  <el-table
                    :data="filteredResults"
                    border
                    stripe
                    class="modern-table results-table"
                    :max-height="500"
                    highlight-current-row
                  >
                    <el-table-column prop="ip" label="IP地址" min-width="120" align="center"/>
                    <el-table-column prop="dotflag" label="支持DoT" min-width="100" align="center">
                      <template #default="{ row }">
                        <el-tag :type="row.dotflag ? 'success' : 'danger'" effect="dark">
                          {{ row.dotflag ? '是' : '否' }}
                        </el-tag>
                      </template>
                    </el-table-column>
                    <el-table-column prop="cert_valid" label="证书有效" min-width="100" align="center">
                      <template #default="{ row }">
                        <el-tag :type="getCertValidType(row.cert_valid)" effect="dark">
                          {{ formatCertValid(row.cert_valid) }}
                        </el-tag>
                      </template>
                    </el-table-column>
                    <el-table-column prop="self_signed" label="自签名证书" min-width="100" align="center">
                      <template #default="{ row }">
                        <el-tag :type="getSelfSignedType(row.self_signed)" effect="dark">
                          {{ formatSelfSigned(row.self_signed) }}
                        </el-tag>
                      </template>
                    </el-table-column>
                    <el-table-column prop="issuer" label="证书颁发机构" min-width="200" show-overflow-tooltip align="center">
                      <template #default="{ row }">
                        <el-tooltip :content="row.issuer || '未知'" placement="top" :show-after="500">
                          <span class="truncate-text">{{ row.issuer || '--' }}</span>
                        </el-tooltip>
                      </template>
                    </el-table-column>
                    <el-table-column prop="issuer_country" label="证书国家" min-width="100" align="center">
                      <template #default="{ row }">
                        {{ row.issuer_country || '--' }}
                      </template>
                    </el-table-column>
                    <el-table-column prop="tls_version" label="TLS版本" min-width="100" align="center">
                      <template #default="{ row }">
                        {{ row.tls_version || '--' }}
                      </template>
                    </el-table-column>
                    <el-table-column prop="key_length" label="密钥长度" min-width="100" align="center">
                      <template #default="{ row }">
                        {{ row.key_length ? `${row.key_length} bit` : '--' }}
                      </template>
                    </el-table-column>
                    <el-table-column prop="cipher_suite" label="加密算法" min-width="200" show-overflow-tooltip align="center">
                      <template #default="{ row }">
                        <el-tooltip :content="row.cipher_suite || '未知'" placement="top" :show-after="500">
                          <span class="truncate-text">{{ row.cipher_suite || '--' }}</span>
                        </el-tooltip>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>

                <!-- Charts Grid -->
                <div class="charts-grid chart-container">
                  <div class="chart-card">
                    <div class="chart-header">
                      <h3 class="chart-title">DoT 加密算法分布</h3>
                      <el-tooltip content="查看加密算法使用情况统计" placement="top">
                        <el-icon><InfoFilled /></el-icon>
                      </el-tooltip>
                    </div>
                    <div class="chart" ref="cipherSuiteStatsRef"></div>
                  </div>
                  <div class="chart-card">
                    <div class="chart-header">
                      <h3 class="chart-title">证书颁发机构分布</h3>
                      <el-tooltip content="查看证书颁发机构分布情况" placement="top">
                        <el-icon><InfoFilled /></el-icon>
                      </el-tooltip>
                    </div>
                    <div class="chart" ref="selfSignedChart"></div>
                  </div>
                </div>
              </div>
            </transition>

            <!-- Empty State -->
            <transition name="fade">
              <div v-if="!results.length" class="empty-state">
                <el-empty 
                  description="暂无验证记录"
                  :image-size="200"
                >
                  <template #image>
                    <div class="empty-icon-container">
                      <el-icon :size="80" class="empty-icon">
                        <Box />
                      </el-icon>
                    </div>
                  </template>
                  <template #description>
                    <p class="empty-text">上传IP地址文件并点击"开始验证"开始批量验证</p>
                  </template>
                </el-empty>
              </div>
            </transition>
    </div>
  </div>
</template>

<script setup>

import { ref, onMounted, onBeforeUnmount, computed, nextTick } from 'vue'
import axios from 'axios'
import * as echarts from 'echarts'
import { ElNotification } from 'element-plus'
import { Check, Lock, Warning, Key, Upload, InfoFilled, CircleCheckFilled, Box } from '@element-plus/icons-vue'
// PDF导出功能已移除

// 从localStorage加载保存的数据
const loadSavedData = () => {
  const savedData = localStorage.getItem('dotDetectionData')
  if (savedData) {
    try {
      const parsedData = JSON.parse(savedData)
      // 检查数据是否过期（24小时）
      if (Date.now() - parsedData.timestamp > 24 * 60 * 60 * 1000) {
        clearSavedData()
        return null
      }
      return parsedData
    } catch (e) {
      console.error('加载保存的数据失败:', e)
      localStorage.removeItem('dotDetectionData')
    }
  }
  return null
}

// 保存数据到localStorage
const saveData = () => {
  const dataToSave = {
    file: file.value ? { name: file.value.name } : null,
    results: results.value,
    stats: stats.value,
    cipherSuiteStats: cipherSuiteStats.value,
    issuerStats: issuerStats.value,
    uploadBtnText: uploadBtnText.value,
    detectStatus: detectStatus.value,
    timestamp: new Date().getTime()
  }
  localStorage.setItem('dotDetectionData', JSON.stringify(dataToSave))
}

// 清除保存的数据
const clearSavedData = () => {
  localStorage.removeItem('dotDetectionData')
}

// 初始化响应式数据
const file = ref(null)
const results = ref([])
const uploadBtnText = ref('选择IP地址文件')
const detectStatus = ref('DoT一键探测')
const cipherSuiteStats = ref([])
const cipherSuiteStatsRef = ref(null)
const issuerStats = ref([])
const selfSignedChart = ref(null)
const isDragover = ref(false)
const searchQuery = ref('')

const cipherChart = ref(null)
const issuerChart = ref(null)

const stats = ref({
  dot_supported_count: 0,
  cert_valid_count: 0,
  cert_expired_count: 0,
  self_signed_count: 0,
})

// 搜索过滤
const filteredResults = computed(() => {
  if (!searchQuery.value) return results.value
  const query = searchQuery.value.toLowerCase()
  return results.value.filter(item => 
    item.ip.toLowerCase().includes(query) ||
    (item.issuer && item.issuer.toLowerCase().includes(query)) ||
    (item.cipher_suite && item.cipher_suite.toLowerCase().includes(query))
  )
})

// 处理证书有效性显示
const formatCertValid = (value) => {
  if (value === null || value === undefined) return '--'
  return value ? '是' : '否'
}

const getCertValidType = (value) => {
  if (value === null || value === undefined) return 'info'
  return value ? 'success' : 'danger'
}

// 处理自签名证书显示
const formatSelfSigned = (value) => {
  if (value === null || value === undefined) return '--'
  return value ? '是' : '否'
}

const getSelfSignedType = (value) => {
  if (value === null || value === undefined) return 'info'
  return value ? 'warning' : 'success'
}

// 组件挂载时加载保存的数据
onMounted(async () => {
  const savedData = loadSavedData()
  if (savedData) {
    // 不恢复文件对象，只恢复文件名
    file.value = null
    if (savedData.file) {
      uploadBtnText.value = savedData.file.name
      // 如果有结果数据，表示之前有文件被选择过
      if (savedData.results && savedData.results.length > 0) {
        // 创建一个虚拟文件对象用于状态显示
        file.value = { name: savedData.file.name }
      }
    }
    results.value = savedData.results || []
    stats.value = savedData.stats || {
      dot_supported_count: 0,
      cert_valid_count: 0,
      cert_expired_count: 0,
      self_signed_count: 0,
    }
    cipherSuiteStats.value = savedData.cipherSuiteStats || []
    issuerStats.value = savedData.issuerStats || []
    uploadBtnText.value = savedData.uploadBtnText || '选择IP地址文件'
    // 恢复状态，但如果是"正在探测"则重置为默认状态
    detectStatus.value = (savedData.detectStatus === '正在探测' || !savedData.detectStatus) 
      ? 'DoT一键探测' 
      : savedData.detectStatus
  }

  // 等待DOM更新后渲染图表
  if (results.value.length > 0) {
    await nextTick()
    renderCharts()
  }

  window.addEventListener('resize', handleResize)
})

// 组件卸载前清理
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  if (cipherChart.value) {
    cipherChart.value.dispose()
  }
  if (issuerChart.value) {
    issuerChart.value.dispose()
  }
})

// 处理文件拖放
const handleFileDrop = (event) => {
  isDragover.value = false
  const droppedFile = event.dataTransfer.files[0]
  if (droppedFile && droppedFile.name.endsWith('.txt')) {
    handleFileUpload({ target: { files: [droppedFile] } })
  } else {
    ElNotification.error({
      title: '文件类型错误',
      message: '请上传.txt格式的文件',
      duration: 3000
    })
  }
}

// 文件上传
function handleFileUpload(event) {
  const uploadedFile = event.target.files[0]
  if (!uploadedFile) return

  if (!uploadedFile.name.endsWith('.txt')) {
    ElNotification.error({
      title: '文件类型错误',
      message: '请上传.txt格式的文件',
      duration: 3000
    })
    event.target.value = ''
    return
  }

  resetAllData()
  file.value = uploadedFile
  uploadBtnText.value = uploadedFile.name
  detectStatus.value = 'DoT一键探测'
  saveData()
  event.target.value = ''
}

// 重置所有数据
function resetAllData() {
  results.value = []
  stats.value = {
    dot_supported_count: 0,
    cert_valid_count: 0,
    cert_expired_count: 0,
    self_signed_count: 0,
  }
  cipherSuiteStats.value = []
  issuerStats.value = []
  searchQuery.value = ''
  detectStatus.value = 'DoT一键探测' // 重置状态
  
  if (cipherChart.value) {
    cipherChart.value.dispose()
    cipherChart.value = null
  }
  if (issuerChart.value) {
    issuerChart.value.dispose()
    issuerChart.value = null
  }
  clearSavedData()
}

// 批量探测
async function startDetection() {
  if (!file.value) {
    ElNotification.warning({
      title: '提示',
      message: '请先选择一个IP地址文件',
      duration: 3000
    })
    return
  }

  detectStatus.value = '正在探测'
  saveData()

  const formData = new FormData()
  formData.append('file', file.value)

  try {
    const res = await axios.post('http://8.163.29.103:9000/dot-batch-check', formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      timeout: 300000 // 5分钟超时
    })

    // 适配新的响应格式
    if (res.data.code === 200 && res.data.data) {
      results.value = res.data.data
    } else {
      throw new Error(res.data.message || '服务器返回错误')
    }

    let dot_supported = 0, cert_valid = 0, cert_expired = 0, self_signed = 0
    const cipherSuiteCount = {}
    const issuerCountMap = {}

    for (const item of results.value) {
      const { dotflag, cert_valid: valid, self_signed: signed, cipher_suite, issuer, issuer_country } = item
      if (dotflag) dot_supported++
      // 只有明确为true的才算有效，null和false都算无效
      if (valid === true) cert_valid++
      else if (valid === false) cert_expired++
      // null值不计入统计
      if (signed === true) self_signed++
      if (cipher_suite) {
        cipherSuiteCount[cipher_suite] = (cipherSuiteCount[cipher_suite] || 0) + 1
      }
      if (issuer) {
        const key = issuer + '-' + (issuer_country || '--')
        if (!issuerCountMap[key]) {
          issuerCountMap[key] = { name: issuer, country: issuer_country || '--', count: 1 }
        } else {
          issuerCountMap[key].count++
        }
      }
    }

    stats.value = {
      dot_supported_count: dot_supported,
      cert_valid_count: cert_valid,
      cert_expired_count: cert_expired,
      self_signed_count: self_signed,
    }
    
    cipherSuiteStats.value = Object.entries(cipherSuiteCount)
      .map(([name, value]) => ({ name, value }))
      .sort((a, b) => b.value - a.value)
    
    issuerStats.value = Object.values(issuerCountMap)
      .sort((a, b) => b.count - a.count)
      .slice(0, 10)

    renderCharts()
    detectStatus.value = 'DoT一键探测'
    saveData()

    ElNotification.success({
      title: '探测完成',
      message: `成功探测 ${results.value.length} 个IP地址`,
      duration: 3000
    })
  }
  catch (err) {
    console.error('探测失败:', err)
    ElNotification.error({
      title: '探测失败',
      message: err.message || '请检查网络连接',
      duration: 3000
    })
    detectStatus.value = 'DoT一键探测'
    saveData()
  }
}

// 渲染图表
function renderCharts() {
  // 加密算法饼图
  const chartDom = cipherSuiteStatsRef.value
  if (!chartDom) {
    console.warn('Chart DOM element not found for cipher suite stats')
    return
  }
  
  // 如果图表已存在，先销毁
  if (cipherChart.value) {
    cipherChart.value.dispose()
  }
  
  cipherChart.value = echarts.init(chartDom)
  cipherChart.value.setOption({
    tooltip: {
      trigger: 'item',
      formatter: '{b}: {c} ({d}%)'
    },
    legend: {
      top: '5%',
      left: 'center',
      type: 'scroll'
    },
    series: [
      {
        name: '加密算法',
        type: 'pie',
        radius: ['40%', '70%'],
        center: ['50%', '60%'],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 15,
          borderColor: '#fff',
          borderWidth: 2
        },
        label: { show: false, position: 'center' },
        emphasis: {
          label: {
            show: true,
            fontSize: 30,
            fontWeight: 'bold'
          }
        },
        labelLine: { show: false },
        data: cipherSuiteStats.value
      }
    ]
  })

  // 证书颁发机构柱状图
  const issuerDom = selfSignedChart.value
  if (issuerDom && issuerStats.value.length > 0) {
    // 如果图表已存在，先销毁
    if (issuerChart.value) {
      issuerChart.value.dispose()
    }
    
    issuerChart.value = echarts.init(issuerDom)
    issuerChart.value.setOption({
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: issuerStats.value.map(item => item.name),
        axisLabel: {
          interval: 0,
          rotate: 30
        }
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          name: '证书数量',
          type: 'bar',
          data: issuerStats.value.map(item => ({
            name: item.name,
            value: item.count,
            country: item.country
          })),
          itemStyle: {
            color: '#409EFF'
          }
        }
      ]
    })
  }
}

// 处理窗口大小变化
const handleResize = () => {
  if (cipherChart.value) {
    cipherChart.value.resize()
  }
  if (issuerChart.value) {
    issuerChart.value.resize()
  }
}

// 导出结果
function downloadResult() {
  if (results.value.length === 0) {
    ElNotification.warning({
      title: '提示',
      message: '没有可导出的数据',
      duration: 3000
    })
    return
  }

  const exportData = {
    meta: {
      export_time: new Date().toISOString(),
      total_records: results.value.length
    },
    results: results.value,
    statistics: stats.value,
    cipher_suite_stats: cipherSuiteStats.value,
    issuer_stats: issuerStats.value
  }

  const blob = new Blob([JSON.stringify(exportData, null, 2)], {
    type: 'application/json',
  })
  const filename = `dot_detection_results_${new Date().toISOString().slice(0,10)}.json`
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = filename
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(url)
}

// 导入JSON结果功能
const importResults = async () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.json'
  input.onchange = (event) => {
    const file = event.target.files[0]
    if (!file) return

    const reader = new FileReader()
    reader.onload = async (e) => {
      try {
        const importedData = JSON.parse(e.target.result)
        
        // 验证数据格式
        if (!importedData.results || !Array.isArray(importedData.results)) {
          ElNotification.error({
            title: '导入失败',
            message: '文件格式不正确，请选择有效的JSON文件',
            duration: 3000
          })
          return
        }

        // 清除现有数据
        resetAllData()

        // 导入数据
        results.value = importedData.results
        stats.value = importedData.statistics || {
          dot_supported_count: 0,
          cert_valid_count: 0,
          cert_expired_count: 0,
          self_signed_count: 0,
        }

        // 重新计算统计数据（防止数据不一致）
        let dot_supported = 0, cert_valid = 0, cert_expired = 0, self_signed = 0
        const cipherSuiteCount = {}
        const issuerCountMap = {}

        for (const item of results.value) {
          const { dotflag, cert_valid: valid, self_signed: signed, cipher_suite, issuer, issuer_country } = item
          if (dotflag) dot_supported++
          // 只有明确为true的才算有效，null和false都算无效
          if (valid === true) cert_valid++
          else if (valid === false) cert_expired++
          // null值不计入统计
          if (signed === true) self_signed++
          if (cipher_suite) {
            cipherSuiteCount[cipher_suite] = (cipherSuiteCount[cipher_suite] || 0) + 1
          }
          if (issuer) {
            const key = issuer + '-' + (issuer_country || '--')
            if (!issuerCountMap[key]) {
              issuerCountMap[key] = { name: issuer, country: issuer_country || '--', count: 1 }
            } else {
              issuerCountMap[key].count++
            }
          }
        }

        stats.value = {
          dot_supported_count: dot_supported,
          cert_valid_count: cert_valid,
          cert_expired_count: cert_expired,
          self_signed_count: self_signed,
        }
        
        cipherSuiteStats.value = Object.entries(cipherSuiteCount)
          .map(([name, value]) => ({ name, value }))
          .sort((a, b) => b.value - a.value)
        
        issuerStats.value = Object.values(issuerCountMap)
          .sort((a, b) => b.count - a.count)
          .slice(0, 10)

        // 更新状态
        uploadBtnText.value = '已导入数据'
        detectStatus.value = 'DoT一键探测'
        file.value = { name: '导入的JSON文件' }

        // 保存到localStorage
        saveData()

        // 等待DOM更新后再渲染图表
        await nextTick()
        // 添加小延迟确保容器尺寸正确
        setTimeout(() => {
          renderCharts()
        }, 100)

        ElNotification.success({
          title: '导入成功',
          message: `成功导入 ${results.value.length} 条记录`,
          duration: 3000
        })

      } catch (error) {
        console.error('导入失败:', error)
        ElNotification.error({
          title: '导入失败',
          message: '文件解析错误，请检查文件格式',
          duration: 3000
        })
      }
    }
    reader.readAsText(file)
  }
  input.click()
}

</script>

<style scoped>
.page-container {
  height: 100vh;
  background: #f8fafc;
}

.nav-aside {
  position: fixed;
  height: 100vh;
  background-color: transparent;
  z-index: 1000;
  width: 240px !important;
}

.main-container {
  min-height: 100vh;
  margin-left: 240px;
}

.main-content {
  padding: 0;
  overflow-x: hidden;
}

.content-wrapper {
  padding: 2rem;
  height: 100%;
  box-sizing: border-box;
}

/* Header Styles */
.header-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2rem;
  background: linear-gradient(135deg, #1a237e 0%, #0d47a1 100%);
  border-radius: 16px;
  padding: 2rem;
  color: white;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.header-content {
  flex: 1;
}

.main-title {
  font-size: 2rem;
  font-weight: 600;
  margin: 0;
  line-height: 1.2;
}

.subtitle {
  font-size: 1.1rem;
  opacity: 0.9;
  margin: 0.5rem 0 0;
}

/* Upload Section */
.upload-container {
  margin-bottom: 2rem;
}

.upload-card {
  background: white;
  border-radius: 16px;
  padding: 2rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.upload-card.is-dragover {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

.upload-area {
  border: 2px dashed #e2e8f0;
  border-radius: 12px;
  padding: 3rem 2rem;
  text-align: center;
  transition: all 0.3s ease;
  cursor: pointer;
  position: relative;
  margin-bottom: 1.5rem;
}

.upload-area:hover {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

.upload-card.has-file .upload-area {
  border-color: var(--el-color-success);
  background: var(--el-color-success-light-9);
}

.upload-icon {
  font-size: 3rem;
  color: var(--el-color-primary);
  margin-bottom: 1rem;
  transition: all 0.3s ease;
}

.upload-icon.success {
  color: var(--el-color-success);
  animation: checkSuccess 0.5s ease;
}

@keyframes checkSuccess {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

.upload-title {
  font-size: 1.25rem;
  color: var(--el-text-color-primary);
  margin: 0 0 0.5rem;
}

.upload-hint {
  color: var(--el-text-color-secondary);
  margin: 0;
}

.file-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.action-panel {
  display: flex;
  gap: 1rem;
  justify-content: center;
}

.action-button {
  min-width: 120px;
  transition: all 0.3s ease;
}

.primary-action {
  transform: scale(1);
}

.primary-action:hover {
  transform: scale(1.02);
}

/* Results Dashboard */
.results-dashboard {
  animation: fadeIn 0.3s ease;
}

/* Stats Grid */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
  margin-bottom: 2rem;
}

.stat-card {
  background: white;
  border-radius: 16px;
  padding: 1.5rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  transition: transform 0.3s ease;
}

.stat-card:hover {
  transform: translateY(-2px);
}

.stat-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
}

.primary-card .stat-icon {
  background: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
}

.success-card .stat-icon {
  background: var(--el-color-success-light-9);
  color: var(--el-color-success);
}

.warning-card .stat-icon {
  background: var(--el-color-warning-light-9);
  color: var(--el-color-warning);
}

.info-card .stat-icon {
  background: var(--el-color-info-light-9);
  color: var(--el-color-info);
}

.stat-info {
  flex: 1;
}

.stat-value {
  display: block;
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--el-text-color-primary);
  line-height: 1.2;
}

.stat-label {
  display: block;
  color: var(--el-text-color-secondary);
  font-size: 0.875rem;
  margin-top: 0.25rem;
}

/* Results Section */
.results-section {
  background: white;
  border-radius: 16px;
  padding: 1.5rem;
  margin-bottom: 2rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
  gap: 1rem;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.section-title {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--el-text-color-primary);
  margin: 0;
}

.result-count {
  font-size: 0.875rem;
}

.search-input {
  width: 240px;
}

/* Table Styles */
.modern-table {
  margin-bottom: 1.5rem;
}

.truncate-text {
  display: inline-block;
  max-width: 200px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Charts Grid */
.charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 1.5rem;
  margin-bottom: 2rem;
}

.chart-card {
  background: white;
  border-radius: 16px;
  padding: 1.5rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}

.chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.chart-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--el-text-color-primary);
  margin: 0;
}

.chart {
  height: 400px;
}

/* Empty State */
.empty-state {
  text-align: center;
  padding: 4rem 2rem;
  background: white;
  border-radius: 16px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}

.empty-icon-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 200px;
  height: 200px;
  margin: 0 auto;
}

.empty-icon {
  color: #c0c4cc;
  opacity: 0.6;
}

.empty-text {
  color: var(--el-text-color-secondary);
  font-size: 1rem;
  margin: 1rem 0 0;
}

/* Animations */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translateY(10px);
}

/* Responsive Design */
@media (max-width: 1024px) {
  .main-container {
    margin-left: 0;
  }
  
  .nav-aside {
    transform: translateX(-100%);
    transition: transform 0.3s ease;
  }
}

@media (max-width: 768px) {
  .content-wrapper {
    padding: 1rem;
  }

  .header-section {
    padding: 1.5rem;
  }

  .main-title {
    font-size: 1.5rem;
  }

  .stats-grid {
    grid-template-columns: 1fr;
  }

  .charts-grid {
    grid-template-columns: 1fr;
  }

  .search-input {
    width: 100%;
  }

  .action-panel {
    flex-direction: column;
  }

  .action-button {
    width: 100%;
  }
}
</style>
